﻿using System;
using Microsoft.SPOT;
using System.IO.Ports;
using System.Text;
using System.Threading;
using System.Collections;

namespace GPSController
{
    public class LS20031 : IDisposable
    {
        public LS20031(SerialPort port)
        {
            this.port = port;

            port.ReadTimeout = 200; //so read call doesn't block forever
            port.Open();
        }

        public void Init_GPS()
        {

            Debug.Print("Message Set");
            //Send(Encoding.UTF8.GetBytes(SET_GGA_RMC_OUT));
            Send(Encoding.UTF8.GetBytes(SET_GLL_OUT));

            Debug.Print("1Hz Set");
            Send(Encoding.UTF8.GetBytes(SET_1HZ_MODE));

            Debug.Print("Init Complete");
            return;
        }

        public delegate void ActionBytes(byte[] output);
        public delegate void Complete();

        const int IN_BUFFER_SIZE = 255;
        static byte[] InBuffer = new byte[IN_BUFFER_SIZE];

        const int COMMAND_SIZE = 7; 

        public bool Poll_GPS(ActionBytes superduper)
        {
            Read(1);
            Read(IN_BUFFER_SIZE);

            //foreach (var bytes in InBuffer)
            //{
            //    if (bytes.Equals(null))
            //        Debug.Print("NULL FOUND");
            //    Debug.Print(bytes.ToString());
            //}
            //Debug.Print("End Null report");

            if (!InBuffer[0].Equals(null))
                superduper(NewArray(IN_BUFFER_SIZE));
            else
            {
                Debug.Print("Fail poll");
                return false;
            }
            
            return true;
        }

        private byte[] NewArray(int chunkLength)
        {
            //make new array for bytes event so receiver can consume
            //in sep thread without it changing during processing
            var chunk = new byte[chunkLength];
            Array.Copy(InBuffer, chunk, chunkLength);
            return chunk;
        }


        byte[] junkBuffer = new byte[IN_BUFFER_SIZE];
        private void ReadAllRemaining()
        {
            int readCount = 0;

            do
            {
                readCount = Read(junkBuffer, IN_BUFFER_SIZE);
            } while (readCount != 0);
        }

        private int Read()
        {
            return Read(IN_BUFFER_SIZE);
        }

        private int Read(int bytes)
        {
            return Read(InBuffer, bytes);
        }

        private int Read(byte[] buffer, int bytes)
        {
            return port.Read(buffer, 0, bytes);
        }

        private void Send(byte[] command)
        {
            port.Write(command, 0, command.Length);
        }

       // static readonly string SET_BAUD_38400 = "$PMTK251,38400*27\r\n";

        static readonly string SET_GGA_RMC_OUT = "$PMTK314,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*28\r\n";
        static readonly string SET_GLL_OUT = "$PMTK314,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*29\r\n";

        static readonly string SET_5HZ_MODE = "$PMTK220,200*2C\r\n";
        static readonly string SET_1HZ_MODE = "$PMTK220,1000*1F\r\n";

        SerialPort port;

        private bool AreEqual(byte[] left, int inSize)
        {
            if (left == null || left.Length != inSize)
                return false;

            for (int i = 0; i < left.Length; i++)
                if (left[i] != InBuffer[i])
                    return false;

            return true;
        }

        #region IDisposable Members

        public void Dispose()
        {
            if (port != null)
                port.Dispose();
        }

        #endregion
    }
}